package com.sw.c.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.data.convert.ReadingConverter;
import org.springframework.data.convert.WritingConverter;
import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.convert.*;
import org.springframework.data.mongodb.core.mapping.MongoMappingContext;

import java.util.Date;

@Configuration
public class MongoDBConfig {
    // 注册转换器
    @Bean
    public MongoCustomConversions customConversions() {
        return MongoCustomConversions.create(i -> {
            i.registerConverter(new DateToLongConverter());
            i.registerConverter(new LongToDateConverter());
        });
    }

    /**
     * mongo映射转换器
     * @param factory           mongo工厂
     * @param context           映射命名空间
     * @param customConversions 自定义转换器
     * @return org.springframework.data.mongodb.core.convert.MappingMongoConverter
     */
    @Bean
    public MappingMongoConverter mappingMongoConverter(MongoDatabaseFactory factory, MongoMappingContext context, MongoCustomConversions customConversions) {
        DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory);
        MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context);
        //添加自定义的转换器
        mappingConverter.setCustomConversions(customConversions);
        // 去掉默认mapper添加的_class
        mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null));
        return mappingConverter;
    }

    /**
     * mongo时间转换器(Long转Date)
     **/
    @ReadingConverter
    private static class LongToDateConverter implements Converter<Long, Date> {
        @Override
        public Date convert(Long source) {
            // 判断是否为毫秒,兼容之前存的毫秒级时间
            if (source.toString().length() < 11) {
                return new Date(source * 1000);
            } else return new Date(source);
        }
    }

    /**
     * mongo时间转换器(Date转Long)
     **/
    @WritingConverter
    private static class DateToLongConverter implements Converter<Date, Long> {
        @Override
        public Long convert(Date source) {
            return source.getTime() / 1000;
        }
    }
}
